package com.zmn.oms.dubbo.impl.redistridute;

import com.alibaba.fastjson.JSON;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.consts.GlobalConsts;
import com.zmn.manager.redis.lock.DistributedLock;
import com.zmn.manager.redis.lock.DistributedLockUtils;
import com.zmn.mcc.common.dto.staff.StaffDRO;
import com.zmn.mcc.dubbo.interfaces.staff.StaffListRemoteService;
import com.zmn.oms.common.constant.ConfRedistributeConsts;
import com.zmn.oms.common.constant.OmsErrorCodeConsts;
import com.zmn.oms.common.constant.RedisKeyConsts;
import com.zmn.oms.common.dio.redistribute.OrderWorkRedistributeApplyDIO;
import com.zmn.oms.common.dio.redistribute.OrderWorkRedistributeAuditDIO;
import com.zmn.oms.common.dio.redistribute.OrderWorkRedistributeModifyDIO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.dubbo.interfaces.redistridute.OrderWorkRedistributeModifyRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.model.bo.work.redistribute.OrderWorkRedistributeApplyBO;
import com.zmn.oms.model.bo.work.redistribute.OrderWorkRedistributeAuditBO;
import com.zmn.oms.model.bo.work.redistribute.OrderWorkRedistributeModifyBO;
import com.zmn.oms.zmn.business.interfaces.redistribute.OrderWorkRedistributeApplyBService;
import com.zmn.oms.zmn.business.interfaces.redistribute.RedistributeApplyBService;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import java.util.Objects;

/**
 * 类描述: 改派业务操作远程实现类 供mapp使用
 *
 * @author: HuangChao
 * @since: 2022/05/10 9:11
 */
@Slf4j
@DubboService(loadbalance = "roundrobin", timeout = 10000, retries = 2, version = DubboConsts.INTERFACE_VERSION, validation = "true")
public class OrderWorkRedistributeModifyRemoteServiceImpl implements OrderWorkRedistributeModifyRemoteService {

    @Autowired
    private OrderWorkRedistributeApplyBService orderWorkRedistributeApplyBService;
    @Autowired
    private RedistributeApplyBService redistributeApplyBService;
    @DubboReference(version = com.zmn.mcc.dubbo.dto.DubboConsts.INTERFACE_VERSION, check = false)
    private StaffListRemoteService staffListRemoteService;

    @Override
    public ResponseDTO addRedistributeApply(@Validated @NotNull(message = "新增改派申请数据不能为空") OrderWorkRedistributeApplyDIO applyDIO) {
        log.info("新增改派申请接口入参：{}", JSON.toJSONString(applyDIO));
        String lockKey = String.format(RedisKeyConsts.OMS_REDISTRIBUTE_APPLY_SAVE_KEY, applyDIO.getOrderId());
        DistributedLock lock = DistributedLockUtils.build(lockKey, 5);

        if (!lock.lock()) {
            return ResponseDTO.fail("请勿重复发起申请");
        }

        try {

            OrderWorkRedistributeApplyBO applyBO = BeanMapper.map(applyDIO, OrderWorkRedistributeApplyBO.class);
            applyBO.setProductInfo(applyDIO.getProductName());
            // mapp 调用时 申请人信息取工程师相关信息
            if (NumberUtil.isNullOrZero(applyDIO.getApplyUserId())) {
                applyBO.setApplyUserId(applyDIO.getMasterId().longValue());
                applyBO.setApplyUser(applyDIO.getMasterName());
                applyBO.setApplyUserType(GlobalConsts.OPERATE_USER_TYPE_MASTER);

                applyBO.setLatitude(applyDIO.getEditLatitude());
                applyBO.setLongitude(applyDIO.getEditLongitude());
            }
            applyBO.setOperatorId(applyBO.getApplyUserId());
            applyBO.setOperator(applyBO.getApplyUser());
            applyBO.setOperatorType(applyBO.getApplyUserType());
            applyBO.setOperateTime(DateUtil.getNow());
            redistributeApplyBService.redistributeApply(applyBO);
            return ResponseDTO.success(true, "新增改派申请成功！");
        } catch (OmsBaseException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("[%s]保存改派申请失败，{}", applyDIO.getOrderId()), e);
            return ResponseDTO.fail("保存失败，请稍后重试");
        }finally {
            lock.unlock();
        }
    }

    @Override
    public ResponseDTO cancelRedistributeApplyByRedistributeId(@Validated @NotNull(message = "取消改派申请数据不能为空") OrderWorkRedistributeModifyDIO modifyDIO) {
        log.info("改派取消接口入参：{}", JSON.toJSONString(modifyDIO));
        try {
            OrderWorkRedistributeModifyBO cancelBO = BeanMapper.map(modifyDIO, OrderWorkRedistributeModifyBO.class);
            cancelBO.setOperatorId(Long.valueOf(modifyDIO.getMasterId()));
            cancelBO.setOperator(modifyDIO.getMasterName());
            cancelBO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_MASTER);
            cancelBO.setOperateTime(DateUtil.getNow());
            orderWorkRedistributeApplyBService.cancelRedistributeApply(cancelBO);
            return ResponseDTO.success(true, "取消改派申请成功！");
        } catch (OmsBaseException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("[%s]取消改派申请失败，{}", modifyDIO.getOrderId()), e);
            return ResponseDTO.fail("取消失败，请稍后重试");
        }
    }

    @Override
    public ResponseDTO redistributeTake(@NotNull(message = "接受转单求助数据不能为空") OrderWorkRedistributeModifyDIO orderWorkRedistributeModifyDIO) {
        log.info("接受转单求助接口入参：{}", JSON.toJSONString(orderWorkRedistributeModifyDIO));
        try {
            OrderWorkRedistributeModifyBO takeBO = BeanMapper.map(orderWorkRedistributeModifyDIO, OrderWorkRedistributeModifyBO.class);
            takeBO.setOperatorId(Long.valueOf(orderWorkRedistributeModifyDIO.getMasterId()));
            takeBO.setOperator(orderWorkRedistributeModifyDIO.getMasterName());
            takeBO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_MASTER);
            takeBO.setOperateTime(DateUtil.getNow());
            redistributeApplyBService.redistributeTake(takeBO);
            return ResponseDTO.success(true, "接受转单求助成功！");
        } catch (OmsBaseException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("[%s]转单求助领单失败，{}", orderWorkRedistributeModifyDIO.getOrderId()), e);
            return ResponseDTO.fail(OmsErrorCodeConsts.ERROR_GRAB_ORDER_CODE, "转单求助领单失败，请稍后重试");
        }
    }

    @Override
    public ResponseDTO supervisorAuditRedistribute(@NotNull(message = "审核数据不为空") OrderWorkRedistributeAuditDIO auditDIO) {
        log.debug("工程师主管审核改派申请接口入参：{}", JSON.toJSONString(auditDIO));
        try {
            ResponseDTO<StaffDRO> responseDTO = staffListRemoteService.getStaffByDingTalkId(auditDIO.getDingTalkId());
            log.info("staffListRemoteService.getStaffByDingTalkId params={} response={}", auditDIO.getDingTalkId(), JSON.toJSONString(responseDTO));
            StaffDRO staffDRO = responseDTO.getData();
            if (!responseDTO.isSuccess() || Objects.isNull(staffDRO)) {
                return ResponseDTO.fail("通过钉钉用户id获取员工信息失败");
            }
            OrderWorkRedistributeAuditBO auditBO = BeanMapper.map(auditDIO, OrderWorkRedistributeAuditBO.class);
            auditBO.setAuditerId(staffDRO.getStaffId().longValue());
            auditBO.setAuditer(staffDRO.getRealName());
            auditBO.setAuditerType(ConfRedistributeConsts.AUDIT_TYPE_MANAGER);
            auditBO.setOperatorId(staffDRO.getStaffId().longValue());
            auditBO.setOperator(staffDRO.getRealName());
            auditBO.setOperatorType(GlobalConsts.OPERATE_USER_TYPE_MASTER);
            auditBO.setOperateTime(DateUtil.getNow());
            redistributeApplyBService.redistributeAudit(auditBO);
            return ResponseDTO.success(true, "工程师主管审核改派申请成功！");
        } catch (OmsBaseException e) {
            return ResponseDTO.fail(e.getCode(), e.getMessage());
        } catch (Exception e) {
            log.error(String.format("[%s]工程师主管审核改派申请失败，{}", auditDIO.getRedistributeId()), e);
            return ResponseDTO.fail("工程师主管审核改派申请失败，请稍后重试");
        }
    }
}